/**
 * 标签页服务模块
 * 处理标签页相关的操作和监听
 */

import { TabInfo } from "@utils/types";

export class TabService {
  private static instance: TabService;
  private tabListeners: Set<(tabInfo: TabInfo) => void> = new Set();
  private updateListeners: Set<(tabId: number, changeInfo: any, tabInfo: TabInfo) => void> = new Set();

  private constructor() {
    this.initializeListeners();
  }

  static getInstance(): TabService {
    if (!TabService.instance) {
      TabService.instance = new TabService();
    }
    return TabService.instance;
  }

  /**
   * 获取当前活动标签页信息
   */
  async getCurrentTab(): Promise<TabInfo | null> {
    try {
      const [tab] = await browser.tabs.query({ active: true, currentWindow: true });
      if (!tab || !this.isTabScriptable(tab)) return null;
      return this.formatTabInfo(tab);
    } catch (error) {
      console.error("Failed to get current tab:", error);
      return null;
    }
  }

  /**
   * 获取所有标签页信息
   */
  async getAllTabs(): Promise<TabInfo[]> {
    try {
      const tabs = await browser.tabs.query({});
      return tabs.map((tab) => this.formatTabInfo(tab));
    } catch (error) {
      console.error("Failed to get all tabs:", error);
      return [];
    }
  }

  /**
   * 根据ID获取标签页信息
   */
  async getTabById(tabId: number): Promise<TabInfo | null> {
    try {
      const tab = await browser.tabs.get(tabId);
      if (!tab || !this.isTabScriptable(tab)) return null;
      return this.formatTabInfo(tab);
    } catch (error) {
      console.error(`Failed to get tab ${tabId}:`, error);
      return null;
    }
  }

  /**
   * 查询符合条件的标签页
   */
  async queryTabs(query: { url?: string; title?: string; active?: boolean; windowId?: number }): Promise<TabInfo[]> {
    try {
      const tabs = await browser.tabs.query(query);
      return tabs.map((tab) => this.formatTabInfo(tab));
    } catch (error) {
      console.error("Failed to query tabs:", error);
      return [];
    }
  }

  /**
   * 创建新标签页
   */
  async createTab(options: {
    url?: string;
    active?: boolean;
    windowId?: number;
    index?: number;
  }): Promise<TabInfo | null> {
    try {
      const tab = await browser.tabs.create(options);
      return this.formatTabInfo(tab);
    } catch (error) {
      console.error("Failed to create tab:", error);
      return null;
    }
  }

  /**
   * 更新标签页
   */
  async updateTab(
    tabId: number,
    options: {
      url?: string;
      active?: boolean;
      muted?: boolean;
    }
  ): Promise<TabInfo | null> {
    try {
      const tab = await browser.tabs.update(tabId, options);
      return tab ? this.formatTabInfo(tab) : null;
    } catch (error) {
      console.error(`Failed to update tab ${tabId}:`, error);
      return null;
    }
  }

  /**
   * 关闭标签页
   */
  async closeTab(tabId: number): Promise<boolean> {
    try {
      await browser.tabs.remove(tabId);
      return true;
    } catch (error) {
      console.error(`Failed to close tab ${tabId}:`, error);
      return false;
    }
  }

  /**
   * 重新加载标签页
   */
  async reloadTab(tabId: number, bypassCache = false): Promise<boolean> {
    try {
      await browser.tabs.reload(tabId, { bypassCache });
      return true;
    } catch (error) {
      console.error(`Failed to reload tab ${tabId}:`, error);
      return false;
    }
  }

  /**
   * 激活标签页
   */
  async activateTab(tabId: number): Promise<boolean> {
    try {
      await browser.tabs.update(tabId, { active: true });
      return true;
    } catch (error) {
      console.error(`Failed to activate tab ${tabId}:`, error);
      return false;
    }
  }

  /**
   * 检查标签页是否可以注入脚本
   */
  isTabScriptable(tab: Browser.tabs.Tab): boolean {
    if (!tab.url) return false;

    const url = tab.url.toLowerCase();
    const restrictedProtocols = ["chrome:", "chrome-extension:", "moz-extension:", "edge:", "about:"];

    return !restrictedProtocols.some((protocol) => url.startsWith(protocol));
  }

  /**
   * 获取可注入脚本的标签页
   */
  async getScriptableTabs(): Promise<TabInfo[]> {
    const allTabs = await this.getAllTabs();
    return allTabs.filter((tab) => tab.url && this.isTabScriptable(tab as any));
  }

  /**
   * 添加标签页创建监听器
   */
  onTabCreated(callback: (tabInfo: TabInfo) => void): void {
    this.tabListeners.add(callback);
  }

  /**
   * 添加标签页更新监听器
   */
  onTabUpdated(callback: (tabId: number, changeInfo: any, tabInfo: TabInfo) => void): void {
    this.updateListeners.add(callback);
  }

  /**
   * 移除标签页创建监听器
   */
  removeTabCreatedListener(callback: (tabInfo: TabInfo) => void): void {
    this.tabListeners.delete(callback);
  }

  /**
   * 移除标签页更新监听器
   */
  removeTabUpdatedListener(callback: (tabId: number, changeInfo: any, tabInfo: TabInfo) => void): void {
    this.updateListeners.delete(callback);
  }

  /**
   * 格式化标签页信息
   */
  private formatTabInfo(tab?: Browser.tabs.Tab | null): TabInfo {
    if (!tab) return {};
    return {
      id: tab.id,
      url: tab.url,
      title: tab.title,
      active: tab.active,
      windowId: tab.windowId,
    };
  }

  /**
   * 初始化标签页事件监听器
   */
  private initializeListeners(): void {
    // 监听标签页创建
    browser.tabs.onCreated.addListener((tab) => {
      const tabInfo = this.formatTabInfo(tab);
      this.tabListeners.forEach((callback) => {
        try {
          callback(tabInfo);
        } catch (error) {
          console.error("Error in tab created listener:", error);
        }
      });
    });

    // 监听标签页更新
    browser.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
      const tabInfo = this.formatTabInfo(tab);
      this.updateListeners.forEach((callback) => {
        try {
          callback(tabId, changeInfo, tabInfo);
        } catch (error) {
          console.error("Error in tab updated listener:", error);
        }
      });
    });

    // 监听标签页激活
    browser.tabs.onActivated.addListener(async (activeInfo) => {
      try {
        const tab = await browser.tabs.get(activeInfo.tabId);
        const tabInfo = this.formatTabInfo(tab);
        this.tabListeners.forEach((callback) => {
          try {
            callback(tabInfo);
          } catch (error) {
            console.error("Error in tab activated listener:", error);
          }
        });
      } catch (error) {
        console.error("Error handling tab activation:", error);
      }
    });
  }

  /**
   * 获取标签页统计信息
   */
  async getTabStats(): Promise<{
    total: number;
    active: number;
    scriptable: number;
    byDomain: Record<string, number>;
  }> {
    try {
      const allTabs = await this.getAllTabs();
      const activeTabs = allTabs.filter((tab) => tab.active);
      const scriptableTabs = await this.getScriptableTabs();

      // 按域名统计
      const byDomain: Record<string, number> = {};
      allTabs.forEach((tab) => {
        if (tab.url) {
          try {
            const domain = new URL(tab.url).hostname;
            byDomain[domain] = (byDomain[domain] || 0) + 1;
          } catch {
            // 忽略无效URL
          }
        }
      });

      return {
        total: allTabs.length,
        active: activeTabs.length,
        scriptable: scriptableTabs.length,
        byDomain,
      };
    } catch (error) {
      console.error("Failed to get tab stats:", error);
      return {
        total: 0,
        active: 0,
        scriptable: 0,
        byDomain: {},
      };
    }
  }
}
